package com.blast.manager.net.presenter

import android.content.Context
import android.text.TextUtils
import com.alibaba.fastjson.JSONObject
import com.blast.manager.blast.BlastActivity
import com.blast.manager.blast.presenter.BlastSerialPresenter
import com.blast.manager.net.NetCheckActivity
import com.blast.manager.presenter.ScanOnlineLGPresenter
import com.wxl.common.life.ViewModelQuick
import com.wxl.common.room.entity.LeiGuanDelayEntity
import com.wxl.common.room.entity.LeiGuanEntity
import com.wxl.common.room.helper.DBHelper
import com.wxl.common.serialport.*
import com.wxl.common.util.ObservableUtil
import com.wxl.common.util.SerialUtil
import com.wxl.common.util.Toll
import com.wxl.common.viewmodel.AbsPresenter
import com.wxl.common.wiget.ProgressUpdatePop
import io.reactivex.ObservableOnSubscribe

class NetCheckPortPresenter : AbsPresenter() {

    lateinit var context: Context
    var mCurrentDetonatorNum = 0
    val defPassword = "00000000"
    val data: ArrayList<LeiGuanEntity> = arrayListOf()
    var scanProgress = 0

    override fun onCreated(vararg args: Any) {
        context = args[0] as Context
        if (!isBlast()) {
            SerialPortManager.openOnlyPort(object : SerialPortManager.Companion.OpenPortCallback {
                override fun onOpenPort(state: Int) {
                    if (state != 0) {
                        Toll.toll("串口打开失败！")
                    }
                }
            })
        }
    }


    private fun isBlast(): Boolean {
        return context is BlastActivity
    }


    /**
     * 检查是否为延时方案
     */
    fun checkIsDelayPlan(data: List<LeiGuanEntity>) {
        ProgressUpdatePop.updateProgress(4, "正在检查延时方案...", "检查延时方案", 100)
        DBHelper.queryLeiGuanDelayEntity(object :
            ObservableUtil.Companion.OnNextCallback<List<LeiGuanDelayEntity>>() {
            override fun onNext(t: List<LeiGuanDelayEntity>) {
                if (t.isNotEmpty() && t.size == data.size) {
                    checkDelayPlan(data, t)
                } else {
                    this@NetCheckPortPresenter.data.addAll(data)
                    if (isBlast()) {
                        getBlastActivity().addLog("下传方案", 0, "下传延时方案")
                    } else {
                        getActivity().addLog("下传方案", 0, "下传延时方案")
                    }
                    sendDelayPlanCode()
                }
            }
        })
    }

    /**
     * 比较两个数组，检查延时方案是否不一致
     */
    private fun checkDelayPlan(data: List<LeiGuanEntity>, delayData: List<LeiGuanDelayEntity>) {
        this.data.addAll(data)
        ObservableUtil.doNext(ObservableOnSubscribe {
            val uids = arrayListOf<String>()
            data.forEach { lge ->
                for ((i, ldge) in delayData.withIndex()) {
                    if (!uids.contains(ldge.UID)) {
                        uids.add(ldge.UID)
                    }

                    if (!TextUtils.isEmpty(lge.state)) {
                        if (TextUtils.equals("0", lge.state.toCharArray()[5].toString())) {
                            it.onNext(true)
                            return@ObservableOnSubscribe
                        }
                    }

                    takeIf {
                        TextUtils.equals(lge.UID, ldge.UID) && !TextUtils.equals(
                            lge.delay,
                            ldge.delay
                        )
                                || !TextUtils.isEmpty(lge.password) && !TextUtils.isEmpty(ldge.password) && !TextUtils.equals(
                            ldge.password,
                            lge.password
                        )
                                || !TextUtils.isEmpty(lge.holeNumber) && !TextUtils.isEmpty(ldge.holeNumber) && !TextUtils.equals(
                            ldge.holeNumber,
                            lge.holeNumber
                        )
                                || !TextUtils.isEmpty(lge.collectorNumber) && !TextUtils.isEmpty(
                            ldge.collectorNumber
                        ) && !TextUtils.equals(ldge.collectorNumber, lge.collectorNumber)
                    }?.run {
                        it.onNext(true)
                        return@ObservableOnSubscribe
                    }

                    if (i >= delayData.size - 1 && !uids.contains(lge.UID)) {
                        it.onNext(true)
                        return@ObservableOnSubscribe
                    }

                }
            }

            uids.clear()
            it.onNext(false)

        }, object : ObservableUtil.Companion.OnNextCallback<Boolean>() {
            override fun onNext(t: Boolean) {
                if (t) {
                    sendDelayPlanCode()
                } else {
                    onScanOnlinePlan()
                }
            }
        })
    }

    /**
     * 发送延时方案命令,下传该延时方案
     */
    private fun sendDelayPlanCode() {
        ProgressUpdatePop.updateProgress(5, "正在下传延时方案...($mCurrentDetonatorNum)", "检查延时方案", 100)
        SerialPortManager.cancelIntervalWork()
        Serials.registerSingleStartHexSerial(CmdCode.DELAY_PLAN_OK_ASK, object : Serial() {
            override fun loadReceiveData(data: String) {//成功
                if (mCurrentDetonatorNum < this@NetCheckPortPresenter.data.size - 1) {
                    mCurrentDetonatorNum++
                    sendDelayPlanCode()
                } else {
                    saveUnderDelayPlan()
                }
            }
        })
        Serials.registerSingleStartHexSerial(CmdCode.DELAY_PLAN_E_ASK, object : Serial() {
            override fun loadReceiveData(data: String) {//失败
                if (isBlast()) {
                    getBlastActivity().dismissClearAllPop()
                    getBlastActivity().addLog("下传方案", 0, "同步异常！")
                    getBlastActivity().showOnlyBack()
                    getBlastActivity().showText("同步异常！")
                } else {
                    getActivity().dismissClearAllPop()
                    getActivity().addLog("下传方案", 0, "同步异常！")
                    getActivity().showOnlyBack()
                    getActivity().showText(true, "同步异常！")
                }
            }
        })
        val makeData = getMakeData(mCurrentDetonatorNum, data)
        SerialPortManager.send(CmdCode.DELAY_PLAN_CMD + makeData)
    }

    /**
     * 获取组装数据
     */
    private fun getMakeData(num: Int, list: List<LeiGuanEntity>): String? {
        val sb = StringBuffer()
        val number: String = SerialUtil.getCurrentDetonatorNum(num)
//        val hexString: String = StringUtils.HexToBin16(list[num].holeNumber)
//        val row: String = StringUtils.getRowNumber(hexString).toString()
//        val hole: String = StringUtils.getHoleNumber(hexString).toString()
        val total: String = SerialUtil.getCurrentDetonatorNum(list.size)
        //        PLog.e("cuowu", "串口响应下传延时孔位==" + list.get(num).holeNumber);
        sb.append(number).append(total).append(list[num].UID)
        sb.append(if (!TextUtils.isEmpty(list[num].password)) list[num].password else defPassword)
        sb.append(SerialUtil.getCurrentDetonatorNum(list[num].delay.toInt()))
        sb.append(
            SerialUtil.getCurrentDetonatorNum(
                Integer.valueOf(
                    list[num].holeNumber,
                    16
                )
            )
        )
        sb.append("00")
//        val str: String =
//            SerialUtil.getCurrentDetonatorNum(list[num].delay.toInt())
        //        PLog.e("方案下传","下传延时十六进制=="+str+",十进制=="+list.get(num).delay+",number=="+num);
        return sb.toString()
    }


    /**
     * 保存下传好的方案
     */
    private fun saveUnderDelayPlan() {
        ObservableUtil.doNext(ObservableOnSubscribe {
            val delayData = arrayListOf<LeiGuanDelayEntity>()
            data.forEach {
                val toJSONString = JSONObject.toJSONString(it)
                val delayEntity =
                    JSONObject.parseObject(toJSONString, LeiGuanDelayEntity::class.java)
                delayData.add(delayEntity)
            }
            it.onNext(delayData)
        }, object : ObservableUtil.Companion.OnNextCallback<List<LeiGuanDelayEntity>>() {
            override fun onNext(t: List<LeiGuanDelayEntity>) {
                DBHelper.insertNewLeiGuanDelayData(object :
                    ObservableUtil.Companion.OnNextCallback<Boolean>() {
                    override fun onNext(t: Boolean) {
                        onScanOnlinePlan()
                    }
                }, *t.toTypedArray())
            }
        })
    }


    /**
     * 扫描在线方案(控制器方案)
     */
    private fun onScanOnlinePlan() {
        ProgressUpdatePop.updateProgress(0, "正在扫描控制器方案...", "在线扫描", 100)
        if (!isBlast()) {
            getActivity().addLog("延时组网", 0, "开始组网")
        } else {
            getBlastActivity().addLog("延时组网", 0, "开始组网")
        }
        ViewModelQuick.get(
            if (isBlast()) getBlastActivity() else getActivity(),
            ScanOnlineLGPresenter::class.java
        )
            .start(isBlast(), object : ScanOnlineLGPresenter.OnScanOnlineLGCallback {
                override fun onScanOnlineResult(
                    lgs: ArrayList<LeiGuanEntity>,
                    isNotMatch: Boolean
                ) {
                    if (!isBlast()) {
                        getActivity().addLog("在线扫描", 100, "扫描完成")
                        ProgressUpdatePop.updateProgress(100, "正在扫描控制器方案...", "在线扫描", 100)
                        (if (isBlast()) getBlastActivity() else getActivity()).dismissClearAllPop()
                    }
                    if (isNotMatch && !isBlast()) {
                        ViewModelQuick.get(
                            if (isBlast()) getBlastActivity() else getActivity(),
                            NetCheckErrorPresenter::class.java
                        )
                            .checkNotMatchData(lgs, isBlast())
                    } else {
                        if (!isBlast()) {
                            getActivity().addLog("组网成功", 100, "组网成功")
                            getActivity().showText(false, "验证成功。\n 检测到雷管：${lgs.size} 发")
                        } else {
                            (context as BlastActivity).addLog("充电起爆",0,"正在进行授权验证")
                            startAuthProveBlast()
                        }
                    }
                }

                override fun onScanNotMatchResult(
                    isNeedDelay: Boolean,
                    isNotMatch: Boolean,
                    state: Int,
                    lgs: ArrayList<LeiGuanEntity>
                ) {

                }

                override fun onScanOnlineProgress(title: String, p: Int, total: Int) {
                    ProgressUpdatePop.updateProgress(p, title, "在线扫描", total + 1)
                }

                override fun onScanChargeChanged(mVoltage: Int, mElectric: Int) {
                    ViewModelQuick.get(
                        if (isBlast()) getBlastActivity() else getActivity(),
                        NetCheckChargePresenter::class.java
                    ).onChargeElectricChanged(mVoltage, mElectric)
                }

                override fun onScanOnlineFailed(e: String) {
                    ProgressUpdatePop.updateProgress(-1, e, "在线扫描", 100)
                    if (!isBlast()) {
                        getActivity().addLog("延时组网", 100, e)
                        getActivity().dismissClearAllPop()
                        getActivity().showText(true, e)
                    } else {
                        getBlastActivity().addLog("延时组网", 100, e)
                        getBlastActivity().dismissClearAllPop()
                        getBlastActivity().showText(e)
                    }
                }

            })
    }


    /**
     * 走起爆授权/延时流程
     */
    private fun startAuthProveBlast() {
        ProgressUpdatePop.updateProgress(98, "正在进行授权验证...", "授权验证", 100)
        ViewModelQuick.get((context as BlastActivity), BlastSerialPresenter::class.java)
            .sendAuthProve(object : BlastSerialPresenter.OnAuthDelayCallback {

                override fun onAuthDelayResult() {
                    getBlastActivity().addLog("授权验证", 100, "授权验证成功")
                    ProgressUpdatePop.updateProgress(100, "授权验证成功...", "授权验证", 100)
                    (if (isBlast()) getBlastActivity() else getActivity()).dismissClearAllPop()
                    getBlastActivity().showChargeReadyLayout()
                }

                override fun onChargeProgress(p: Int, sub: String, max: Int) {
                    ProgressUpdatePop.updateProgress(p, sub, "授权验证", max)
                }

                override fun onVoltageElectricChanged(
                    mVoltage: Int,
                    mElectric: Int
                ) {
                    ViewModelQuick.get(
                        if (isBlast()) getBlastActivity() else getActivity(),
                        NetCheckChargePresenter::class.java
                    ).onChargeElectricChanged(mVoltage, mElectric)
                }

                override fun onChargeProgressError(sub: String) {
                    getBlastActivity().addLog("授权验证", 100, sub)
                    ProgressUpdatePop.updateProgress(-1, sub, "授权验证", 100)
                    (if (isBlast()) getBlastActivity() else getActivity()).dismissClearAllPop()
                    getBlastActivity().showText(sub)
                }
            })
    }

    private fun getActivity(): NetCheckActivity {
        return context as NetCheckActivity
    }

    private fun getBlastActivity(): BlastActivity {
        return context as BlastActivity
    }

    override fun onDestroy() {
        super.onDestroy()
        Serials.unRegisterSingleStartHexSerial(CmdCode.DELAY_PLAN_OK_ASK)
        Serials.unRegisterSingleStartHexSerial(CmdCode.DELAY_PLAN_E_ASK)
    }
}